<template>
    <div class="container" :style="backgroundStyle">
        <!-- 背景遮罩层 -->
        <div class="overlay"></div>

        <!-- 使用Element Plus按钮组件 -->
        <el-button
            class="btn-setting"
            type="primary"
            circle
            @click="showSettingPanel = true"
        >
            <el-icon>
                <Setting />
            </el-icon>
        </el-button>

        <!-- 照片预览 (动态比例) -->
        <div v-if="currentImage" class="photo-preview" :style="previewStyle">
            <img :src="currentImage" alt="签到照片" :style="imageStyle" />
        </div>

        <!-- 拍照按钮 -->
        <el-button
            class="btn-camera"
            type="primary"
            circle
            @click="handlePhotoAction"
        >
            <el-icon>
                <Camera />
            </el-icon>
        </el-button>

        <!-- 签名组件 -->
        <div class="sinature-wrapper">
            <SignaturePad
                ref="signaturePad"
                :wrapStyle="wrapStyle"
                :canvasStyle="signatureStyle"
                :initial-config="{ size: brushSize, color: brushColor }"
            >
                <template #controls> </template>
            </SignaturePad>
        </div>

        <!-- 撤销按钮 -->
        <el-button class="btn-clear" type="danger" circle @click="handleUndo">
            <el-icon>
                <RefreshLeft />
            </el-icon>
        </el-button>

        <!-- 完成按钮 -->
        <el-button
            class="btn-submit"
            type="success"
            circle
            @click="handleSubmit"
        >
            <el-icon>
                <Check />
            </el-icon>
        </el-button>

        <!-- 设置面板 -->
        <el-dialog
            v-model="showSettingPanel"
            title="签名设置"
            width="90%"
            top="5vh"
        >
            <div class="setting-content">
                <div class="setting-item">
                    <label>笔迹粗细: {{ brushSize }}px</label>
                    <PassiveSlider v-model="brushSize" :min="1" :max="10" />
                </div>

                <div class="setting-item">
                    <label>笔迹颜色</label>
                    <el-color-picker v-model="brushColor" />
                </div>
            </div>
        </el-dialog>

        <!-- 隐藏的文件输入 -->
        <input
            type="file"
            ref="fileInput"
            accept="image/*"
            capture="environment"
            @change="handleFileUpload"
            style="display: none"
        />
    </div>
</template>

<script setup>
import { Camera, Check, RefreshLeft, Setting } from '@element-plus/icons-vue';
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { ElMessage, ElSlider } from 'element-plus';
import PassiveSlider from '@/components/common/PassiveSlider.vue';
import SignaturePad from '@/components/common/SignaturePad.vue';

// 响应式数据
const aid = ref('');
const st = ref('');
const currentImage = ref(null);
const showSettingPanel = ref(false);
const brushSize = ref(3);
const brushColor = ref('#000000');
const fileInput = ref(null);
const stream = ref(null);
const signaturePad = ref(null);
const backgroundImg = ref('');

const signatureStyle = ref({
    background: '#409eff',
    backgroundColor: 'transparent',
    border: '1px solid #409eff',
});

const wrapStyle = ref({
    'margin-bottom': '5em',
    position: 'absolute',
    width: '50%',
    height: '60%',
    backgroundColor: 'transparent',
});

// 照片比例计算
const photoRatio = computed(() => {
    const ratioMap = { 1: '3/4', 2: '16/9', 3: '1/1' };
    return ratioMap[aid.value] || '3/4';
});

// 背景样式
const backgroundStyle = computed(() => ({
    backgroundImage: `url(${backgroundImg.value})`,
    backgroundSize: 'cover',
    backgroundPosition: 'center',
}));

// 预览样式
const previewStyle = computed(() => ({
    aspectRatio: photoRatio.value,
}));

// 图片样式
const imageStyle = computed(() => ({
    objectFit: ['1/1', '3/4'].includes(photoRatio.value) ? 'cover' : 'contain',
}));

// 初始化
onMounted(() => {
    parseUrlParams();
    backgroundImg.value = `http://${window.location.hostname}:${st.value}/assets/mobile-bg.jpg`;

    // 获取原始Slider渲染函数
    const originalRender = ElSlider.render;

    // 重写渲染函数
    ElSlider.render = function (ctx) {
        const original = originalRender(ctx);

        // 劫持事件监听
        const _on = ctx.$.vnode.props?.on;
        if (_on?.touchstart) {
            _on.touchstart.passive = true;
        }

        return original;
    };
});

// URL参数解析
const parseUrlParams = () => {
    const route = useRoute();
    aid.value = route.query.aid || '1';
    st.value = route.query.st || '';
};

// 拍照处理
const handlePhotoAction = async () => {
    try {
        stream.value = await navigator.mediaDevices.getUserMedia({
            video: {
                facingMode: 'environment',
                width: { ideal: 1280 },
                height: { ideal: 720 },
            },
            audio: false,
        });

        const video = document.createElement('video');
        video.srcObject = stream.value;
        await new Promise((resolve) => (video.onloadedmetadata = resolve));
        video.play();

        const canvas = document.createElement('canvas');
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(video, 0, 0);
        currentImage.value = cropImageToRatio(canvas, photoRatio.value);
        stopCamera();
    } catch (error) {
        console.error('摄像头访问失败:', error);
        fileInput.value.click();
    }
};

// 图片裁剪
const cropImageToRatio = (canvas, ratio) => {
    const [w, h] = ratio.split('/').map(Number);
    const targetRatio = w / h;
    const sourceRatio = canvas.width / canvas.height;

    let sx = 0,
        sy = 0,
        sw = canvas.width,
        sh = canvas.height;
    if (sourceRatio > targetRatio) {
        sw = canvas.height * targetRatio;
        sx = (canvas.width - sw) / 2;
    } else {
        sh = canvas.width / targetRatio;
        sy = (canvas.height - sh) / 2;
    }

    const newCanvas = document.createElement('canvas');
    newCanvas.width = sw;
    newCanvas.height = sh;
    newCanvas.getContext('2d').drawImage(canvas, sx, sy, sw, sh, 0, 0, sw, sh);
    return newCanvas.toDataURL('image/jpeg', 0.8);
};

// 关闭摄像头
const stopCamera = () => {
    stream.value?.getTracks().forEach((track) => track.stop());
    stream.value = null;
};

// 文件上传处理
const handleFileUpload = (e) => {
    const file = e.target.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (event) => {
        const img = new Image();
        img.onload = () => {
            const canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            canvas.getContext('2d').drawImage(img, 0, 0);
            currentImage.value = cropImageToRatio(canvas, photoRatio.value);
        };
        img.src = event.target.result;
    };
    reader.readAsDataURL(file);
    e.target.value = '';
};

// 提交处理
const handleSubmit = () => {
    if (!signaturePad.value) return;
    const signature = signaturePad.value.getSignature();

    console.log('提交数据', {
        aid: aid.value,
        st: st.value,
        signature: signature,
        photo: currentImage.value,
        ratio: photoRatio.value,
    });

    ElMessage.success('签到信息已提交!');
};

// 撤销操作
const handleUndo = () => {
    signaturePad.value?.undo();
};

// 监听画笔参数变化
watch([brushSize, brushColor], ([size, color]) => {
    signaturePad.value?.updateConfig({ size, color });
});

const updateBrushStyle = () => {};

// 清理
onBeforeUnmount(stopCamera);
</script>

<style scoped>
.container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}

.overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
}

.btn-setting {
    position: absolute;
    top: 16px;
    left: 16px;
    z-index: 10;
}

.btn-camera {
    position: absolute;
    top: 16px;
    right: 16px;
    z-index: 10;
}

.btn-clear {
    position: absolute;
    bottom: 16px;
    left: 16px;
    z-index: 10;
}

.btn-submit {
    position: absolute;
    bottom: 16px;
    right: 16px;
    z-index: 10;
}

.photo-preview {
    position: absolute;
    top: 80px;
    left: 16px;
    width: 120px;
    background-color: rgba(255, 255, 255, 0.8);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    z-index: 10;
}

.photo-preview img {
    width: 100%;
    height: 100%;
    display: block;
}

.setting-content {
    padding: 0 16px;
}

.setting-item {
    margin-bottom: 24px;
}

.setting-item label {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    color: #606266;
}

@media (max-width: 480px) {
    .photo-preview {
        width: 100px;
        top: 72px;
    }

    .btn-setting,
    .btn-camera,
    .btn-clear,
    .btn-submit {
        width: 40px;
        height: 40px;
    }
}

.sinature-wrapper {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    padding-bottom: 25px;
    height: 100%;
}
</style>
